﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace NGIS
{
    namespace Model
    {
        public class ModelClass : IModelClass
        {
			private string mName;
            private string mUID;
            private EExecutionStyle mExecutionStyle;

			ModelAttribute mModelAttribute;
			ModelBehavior mModelBehavior;
			ModelRuntime mModelRuntime;
            
			public ModelClass()
			{
				mName = "Model Name";
				mUID = "";
                mExecutionStyle = EExecutionStyle.EES_SIMPLE_CALCULATION;

				mModelAttribute = new ModelAttribute();
				mModelBehavior = new ModelBehavior();
				mModelRuntime = new ModelRuntime();
			}
            
            public void setName(string pName)
            {
                mName = pName; 
            }

            public string getName()
            {
                return mName; 
            }

            public void setUID(string pUID)
            {
                mUID = pUID; 
            }

            public string getUID()
            {
                return mUID;
            }

            public void setExecutionStyle(EExecutionStyle pStyle)
            {
                mExecutionStyle = pStyle;
            }

            public EExecutionStyle getExecutionStyle()
            {
                return mExecutionStyle;
            }

            public IModelAttribute getModelAttribute()
            {
                return mModelAttribute;
            }

            public IModelBehavior getModelBehavior()
            {
                return mModelBehavior;
            }

            public IModelRuntime getModelRuntime()
            {
                return mModelRuntime;
            }

            public bool LoadFromXmlFile(string fileName)
            {
				XmlDocument doc = new XmlDocument();
                doc.Prefix = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
				doc.Load(fileName);
				XmlElement modelClassEle = doc.DocumentElement;             
				mName = modelClassEle.GetAttribute("name");
                mUID = modelClassEle.GetAttribute("uid");               
				string styleStr = "";
				if (modelClassEle.HasAttribute("style")!=false)
					styleStr = modelClassEle.GetAttribute("style");
				else if (modelClassEle.HasAttribute("type")!=false)
                    styleStr = modelClassEle.GetAttribute("type");

				if (styleStr == "SimpleCalculation")
				{
					mExecutionStyle = EExecutionStyle.EES_SIMPLE_CALCULATION;
				}
				else if (styleStr == "TimeSeries")
				{
					mExecutionStyle = EExecutionStyle.EES_TIME_SERIES;
				}
				else
				{
					mExecutionStyle = EExecutionStyle.EES_STATE_SIMULATION;
				}

				mModelAttribute.loadFromXml(modelClassEle);
				mModelBehavior.loadFromXml(modelClassEle);
				mModelRuntime.loadFromXml(modelClassEle);

				return true; 
            }

            public bool FormatToXmlFile(string fileName)
            {
                XmlDocument doc = new XmlDocument();
                XmlElement modelClassEle = doc.CreateElement("ModelClass");
                modelClassEle.SetAttribute("name", mName);
                modelClassEle.SetAttribute("uid", mUID);
                if (mExecutionStyle == EExecutionStyle.EES_SIMPLE_CALCULATION)
                    modelClassEle.SetAttribute("style", "SimpleCalculation");
                else if (mExecutionStyle == EExecutionStyle.EES_TIME_SERIES)
                    modelClassEle.SetAttribute("style", "TimeSeries");
                else
                    modelClassEle.SetAttribute("style", "StateSimulation");

                doc.AppendChild(modelClassEle);
                mModelAttribute.formatToXml(modelClassEle);
                mModelBehavior.formatToXml(modelClassEle);
                mModelRuntime.formatToXml(modelClassEle);

                doc.Save(fileName);

                return true;
            }

            public bool LoadFromXmlStream(string xmlStr)
            {
				XmlDocument doc = new XmlDocument();
				doc.LoadXml(xmlStr);
				XmlElement modelClassEle = doc.DocumentElement;
				mName = modelClassEle.GetAttribute("name");
				mUID = modelClassEle.GetAttribute("uid");
				string styleStr = modelClassEle.GetAttribute("style");
				if (styleStr == "SimpleCalculation")
				{
					mExecutionStyle = EExecutionStyle.EES_SIMPLE_CALCULATION;
				}
				else if (styleStr == "TimeSeries")
				{
                    mExecutionStyle = EExecutionStyle.EES_TIME_SERIES;
				}
				else
				{
                    mExecutionStyle = EExecutionStyle.EES_STATE_SIMULATION;
				}

				mModelAttribute.loadFromXml(modelClassEle);
				mModelBehavior.loadFromXml(modelClassEle);
				mModelRuntime.loadFromXml(modelClassEle);

				return true; 
            }

            public bool FormatToXmlStream(ref string xmlStr)
            {
                XmlDocument doc = new XmlDocument();
                XmlElement modelClassEle = doc.CreateElement("ModelClass");
                modelClassEle.SetAttribute("name", mName);
                modelClassEle.SetAttribute("uid", mUID);
                if (mExecutionStyle == EExecutionStyle.EES_SIMPLE_CALCULATION)
                    modelClassEle.SetAttribute("style", "SimpleCalculation");
                else if (mExecutionStyle == EExecutionStyle.EES_TIME_SERIES)
                    modelClassEle.SetAttribute("style", "TimeSeries");
                else
                    modelClassEle.SetAttribute("style", "StateSimulation");

                doc.AppendChild(modelClassEle);
                mModelAttribute.formatToXml(modelClassEle);
                mModelBehavior.formatToXml(modelClassEle);
                mModelRuntime.formatToXml(modelClassEle);

                xmlStr = doc.InnerXml;

                return true;
            }

            public bool compareOther(IModelClass pClass, bool withRuntime, ref string obj, ref string name)
            {
                bool flag = false;
                if (mModelAttribute != null)
                {
                    flag = mModelAttribute.compareOther(pClass.getModelAttribute(), ref obj, ref name);
                    if (flag == false)
                        return false;
                }
                if (mModelBehavior != null)
                {
                    flag = mModelBehavior.compareOther(pClass.getModelBehavior(), ref obj, ref name);
                    if (flag == false)
                        return false;
                }
                if (withRuntime && mModelRuntime != null)
                {
                    flag = mModelRuntime.compareOther(pClass.getModelRuntime(), ref obj, ref name);
                    if (flag == false)
                        return false;
                }
                return true;
            }
        }
    }
}